--author: anti
--at:2018-03-07

function Split(szFullString, szSeparator)  
local nFindStartIndex = 1  
local nSplitIndex = 1  
local nSplitArray = {}  
while true do  
   local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)  
   if not nFindLastIndex then  
    nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))  
    break  
   end  
   nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)  
   nFindStartIndex = nFindLastIndex + string.len(szSeparator)  
   nSplitIndex = nSplitIndex + 1  
end  
return nSplitArray  
end 

function table.contains(table, element)
  for _, value in pairs(table) do
    if value == element then
      return true
    end
  end
  return false
end

function set_header()
        ngx.status = ngx.OK
        ngx.header['Content-Type'] = 'application/json; charset=utf-8'
	ngx.header["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS, DELETE"
	ngx.header["Access-Control-Allow-Origin"] = "*"
	ngx.header["Access-Control-Allow-Headers"] = "x-requested-with,Content-Disposition,Content-Type"
	ngx.header["Access-Control-Max-Age"] = 3600
end


function ip_check()
	
        local iputils = require("resty.iputils")
	
        local redis = require("resty.redis")
			
        local blocked_ips = {}
        local red = redis:new()
        red:set_timeout(2000) -- 2s
	
        local ok ,err = red:connect("public003.redis.rds.aliyuncs.com",6379)
        if not ok then
		ngx.say("failed", err)
                return
        end
	
        local res, err = red:auth("xpNsEz7Pvn7h0QoM")
        if not res then
                ngx.say("failed to authenticate: ", err)
                return
        end

	
        res , err = red:SMEMBERS("block_ips")
        if not res then
                return
        end
	
        for i, v in ipairs(res) do
                table.insert(blocked_ips,v)
        end

	
        local headers = ngx.req.get_headers()
        --local client_ip = headers["X-FORWARDED-FOR"] or headers["X-REAL-IP"]
        local client_ip = headers["X-FORWARDED-FOR"]
	client_ip = Split(client_ip,',')[1];
	--or ngx.var.remote_addr or headers["X-REAL-IP"]
	--ngx.say ("clientip=",client_ip)

        blocklist = iputils.parse_cidrs(blocked_ips)
        if iputils.ip_in_cidrs(client_ip , blocklist) then
		set_header()
		local resp="{\"code\":200,\"result\":true,\"message\":\"\",\"data\":{\"url\":\"/redirect/login\"},\"md5\":\"9f587448e3752cb59df72f6c98e06d41\",\"city\":\"gz\"}"
        	return ngx.say(resp)
        end

	
        local ip_time_out=60
        local ip_max_count=10
	
		
	ip_count, err = red:get("search-" .. client_ip)
	
	
        if ip_count == ngx.null then
                res , err = red:setex("search-" .. client_ip ,ip_time_out , 1)
		--res , err = red:SADD("block_ips", "search-" .. client_ip)
        else
                ip_count = ip_count + 1
		--ngx.say (ip_count)
                ttl , err = red:ttl("search-" .. client_ip)
                res , err = red:setex("search-" .. client_ip , ttl, ip_count)

                if ip_count >= ip_max_count then
			--set_header()
                        --local resp="{\"code\":200,\"result\":true,\"message\":\"\",\"data\":{\"url\":\"/509.html\"},\"md5\":\"9f587448e3752cb59df72f6c98e06d41\",\"city\":\"gz\"}"
                        --return ngx.say(resp)
                        return ngx.exit(509)
                end
        end
	
        local ok, err = red:set_keepalive(10000, 100)
        if not ok then
                --ngx.say("failed to set keepalive: ", err)
                return
        end

	return
	--ngx.redirect("/shops/search.html")

end

local uid = ngx.var.cookie_uid

if not uid then   --未登陆状态
        --ngx.say("not logined , run ip check")
        ip_check()
end
